home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
yerk
/
mps231ss.hqx
/
Mops ƒ
/
Base
< prev
next >
Wrap
Text File
|
1993-02-02
|
13KB
|
496 lines
\ Nov 88 mrh Mops version.
\ May 90 mrh Changed to trap$ and fdos$ so we will work on 680x0 with
\ instruction cache.
\ Select{ no longer requires default{ - for Neon compatibility.
\ Sept 92 mrh New words etc. moving closer to ANSI standard
false value ECHO? \ echo load to screen?
\ We redefine a few useful words to take advantage of our optimization.
: 1+ ?comp 1 postpone literal postpone + ; immediate
: 2+ ?comp 2 postpone literal postpone + ; immediate
: 3+ ?comp 3 postpone literal postpone + ; immediate
: 4+ ?comp 4 postpone literal postpone + ; immediate
: 1- ?comp 1 postpone literal postpone - ; immediate
: 2- ?comp 2 postpone literal postpone - ; immediate
: 3- ?comp 3 postpone literal postpone - ; immediate
: 4- ?comp 4 postpone literal postpone - ; immediate
: 2* ?comp 1 postpone literal postpone << ; immediate
: 2/ ?comp 1 postpone literal postpone >> ; immediate
: 4* ?comp 2 postpone literal postpone << ; immediate
: 4/ ?comp 2 postpone literal postpone >> ; immediate
\ ANSI words
: CELL+ state IF postpone 4+ else 4 + THEN ; immediate
: CELL- state IF postpone 4- else 4 - THEN ; immediate
: CELLS state IF 2 postpone literal postpone << ELSE 2 << THEN ; immediate
: CHAR+ state IF postpone 1+ else 1 + THEN ; immediate
: CHARS ; immediate
: RECURSE curr-def compile, ; immediate
: SAVE-INPUT
src-start src-len >in @ source-id 4 ;
: RESTORE-INPUT
dup 4 <> IF true EXIT THEN
drop
-> source-id >in ! -> src-len -> src-start false ;
\ .H and U.H print a number in hex, signed and unsigned respectively.
: .H base >r hex . r> -> base ;
: U.H base >r hex u. r> -> base ;
\ =========================
0 constant Z
: NULLOSSTR ['] z ;
: @WORD \ ( -- addr ) Retrieves next blank-delimited word from input stream.
BL word ;
: LIT \ ( n -- ) A state-smart version of LITERAL. Corresponds
\ to LITERAL in Fig-Forth or original Neon, whereas our
\ present LITERAL is Forth-83/ANSI.
state IF postpone literal THEN ; immediate
: 0, 0 , ; \ Compiles an empty cell
: @VAL intrp1 ; \ Compiles a number from input stream
: 'TYPE \ ( -- 4bytes ) OS type literal
pad 4 bl fill @word count 4 min
pad swap cmove pad @ postpone lit ; immediate
create BUF255 256 allot \ buffer for string operations
: >STR255 \ ( addr len addr -- addr )
\ Converts a string to a Str255 at addr
dup >r place r> ;
: STR255 \ ( -- ^buf255 )
buf255 >str255 ;
: $ \ State-smart HEX literal word
base >r
hex Mword number postpone lit
r> -> base ; immediate
: LITW \ ( n -- )
$ 3D3C w, w, ;
: W intrp1 litw ; immediate
\ Trap compilation. We've changed the syntax from Neon's $ xxxx TRAP
\ to TRAP$ xxxx. This is because we are now compiling in-line trap
\ calls, to avoid problems with self-modifying code, and also because Apple
\ are now defining traps that way.
: SAVA5 postpone doSavA5 ;
: RSTA5
$ CD4F w, \ exg a6,a7
$ 2A5F w, ; \ move.l (a7)+,a5
: (TRAP$) \ ( trap# -- ) Compiles a call to the given trap.
SavA5 w, RstA5 ;
: TRAP$ \ ( --<trap#> )
base >r
hex intrp1 (trap$)
r> -> base ; immediate
: (FDOS$) \ ( trap# -- )
$ 205E w, \ move.l (a6)+,a0 ; FCB pointer
SavA5 w, RstA5
$ 48C0 w, \ ext.l d0 ; Result
$ 2D00 w, ; \ move.l d0,-(a6)
: FDOS$ \ ( --<trap#> )
base >r
hex intrp1 (fdos$)
r> -> base ; immediate
\ ==================
: OpenResFile \ ( addr len -- ) Opens named resource file
>r >r word0 r> r> str255
trap$ a997 i->l \ call OpenResFile
-1 = abort" resource file open failed" ;
: OPENMR \ Opens the Mops system resource file if necessary.
MRopen? ?exit \ Do nothing if already open
instld? ?exit \ or if this is an installed application
" mops.rsrc" OpenResFile
true -> MRopen? ;
: CHAR @word 1+ c@ ; \ ANSI - replaces ASCII
: [CHAR] @word 1+ c@ postpone literal ; immediate
: & \ ( -- c ) A shorter state-smart version.
@word 1+ c@ postpone lit ; immediate
: GETSTRING \ ( resID -- addr len ) Get the string with resource ID
openMR
0 swap makeint trap$ a9ba \ call getString
dup if @ count else 0 then ;
: (TSTR) \ ( id# -- ) Prints string with given resID.
getString type ;
: X ['] (tstr) -> tstr ; \ We can't do -> outside a defn till Args loaded
x forget x
\ Our normal error action is to call DIE with an error number. DIE calls
\ SvErr to save the error info, then THROWs the error number. If no error
\ handler has been installed, or only handlers which don't want that number
\ and re-THROW it, the default action for THROW occurs. This calls DFLT-DIE.
: (DDIE) \ ( n -- )
setFwind
+echo 0 -> (err#) \ Clear error indicator from AppleEvents
dflt-err ; \ Display error info and abort
: x ['] (ddie) -> dflt-die ;
x forget x
: ?ERROR \ ( b -- ) Aborts and prints resource string if true.
\ Usage: ?error 999
postpone if
intrp1 ( get err# ) postpone literal postpone die
postpone then ; immediate
: TYPE# \ Prints string for id# in stream
intrp1 postpone lit postpone (tStr) ; immediate
: (.RSTR) \ ( -- ) print "Msg# ..." then string with given resID
." Msg# " dup . ." : " (tStr) ;
: MSG# \ ( -- ) print " Msg#" then string for id# in stream
intrp1 postpone lit postpone (.rStr) ; immediate
\ ============ Resources ===========
: GETRES \ ( type resID -- handle )
0 down makeint trap$ a9a0 ; \ call GetResource
\ ( -- #cells)
: RDEPTH rp0 rp@ - 4 / 2- ;
: ?RDEPTH rdepth 220 > ?error 116 ;
\ ========== Type checking ===========
\ Sometimes we want to check that a non-object parameter to a word is of a
\ certain type. We give it a unique type code and use TYPCHK.
: TYPCHK <> ?error 179 ;
\ ========== Forward definitions ===========
: X setfWind +echo
cr ." From " r@ .id 2 spaces r@ .h 109 die ;
: FORWARD
colHdr
$ 487AFFFE , \ pea (start of this instrn)
['] x here 6 allot
(patch) ;
: :F ?exec 301
here ' (patch) :noname ;
: ;F (;) 301 ?defn ; immediate
forward BLD \ Used in CLASS. Needs to be down here so we never
\ refer to it with a short branch. Kludge?
\ Commonly needed error words. These are forward defined - the main
\ application should provide a sensible definition, with a nice friendly
\ alert box, to tell the user in a nice friendly way that things are up
\ the creek.
forward NOMEM \ Call when (not if!) we run out of memory.
forward I/O_ERR \ ( err# -- ) Call when there's an I/O error.
: OK? \ ( rc -- ) A useful word to use after an I/O op.
?dup 0EXIT I/O_err ;
\ ========= :PROC and ;PROC ============
: :PROC
colHdr here 6 allot
['] procEntry swap 6 cmove
:noname 303 ; immediate
: ;PROC immediate
postpone procExit (;)
303 ?defn ;
\ ======== Various utility words needed later =========
\ BECOME allows restarting at a given word, with all stacks
\ empty. This is necessary in menu handlers and other areas
\ that could create indefinite nesting situations.
' quit vect BECOMECFA
: BE sp0 sp! rp0 rp! becomeCfa quit ;
: (BE) -> becomeCfa be ;
: BECOME \ Usage: Become newWord - compiles code to Be at runtime
state
IF postpone ['] postpone (be)
ELSE ' -> becomeCfa be
THEN ; immediate
: DATETIME
$ 20C @ ;
\ ============ Tables, lists etc. ===============
: ) 123 die ; immediate \ "} or } read when no list is current"
: } 123 die ; immediate
: }OR)? \ ( cfa -- cfa b )
dup ['] } = over ['] ) = or ;
: TABLE
<BUILDS 0 w, here 112
DOES> length ;
: END_TABLE
112 ?pairs
here over - \ table length (excluding length field)
swap 2- w! ; \ store in length field
0 value CNT
: (LITS) \ stack compiled list of values starting at IP
w@(ip) ( count ) dup -> cnt
4* r> tuck + dup >r swap
do i @abs 4 +loop
cnt ;
: XTS{ \ State-smart word to compile or stack a list
\ of xts. Pulls words from stream, until "}".
state IF postpone (lits) here 0 w, THEN
0
BEGIN ' }or)?
NWHILE state IF reloc, else swap THEN 1+
REPEAT
drop state IF swap w! THEN ; immediate
: CFAS{ postpone xts{ ; immediate \ Synonyms for compatibility
: CFAS( postpone xts{ ; immediate
: RESERVE \ ( len -- ) Allot and clear.
here over erase allot ;
\ SCON defines a string constant. Usage:
\
\ scon <name> "a string"
\
\ Runtime: ( -- addr len )
\
\ Change from Neon: the first nonblank char after the name of the SCON
\ becomes the delimiter. So " can be used as usual, but anything else can
\ be used instead, e.g.:
\
\ scon <name> /this string contains " as non-delimiter/
: SCON
<BUILDS bl skip-src+
src-start >in @ + c@ ,dlm-str
DOES> count ;
\ CASE should be used for non-contiguous or dynamically computed values.
\ This is a modified Eaker/Duncan model.
\ Our optimization strategy gives quite good code.
: CASE ?comp 302 ; immediate
: OF
postpone over postpone = postpone if
postpone drop ; immediate
: RANGEOF
postpone within? postpone if
postpone drop ; immediate
: ENDOF
postpone else ; immediate
: ENDCASE immediate
postpone drop
BEGIN dup 302 = NWHILE >resolve REPEAT drop ;
\ TYPE{ defines a Pascal/C-like enumerated type. At this stage we don't give
\ a name to the "type" as such, as we can't do anything really sensible with
\ it. However later we can optionally load the ENUM-TYPE class which is
\ rather more Pascal-like. But even without that, the enumeration is useful
\ by itself.
0 value TYPECNT
' null vect DO_ET \ Hook for handling the ENUM-TYPE
\ class when it's loaded
: ENDLIST? \ ( chr -- b )
latest n>count 1 = down c@ = and
dup IF latest n>link (forget) THEN ;
: TYPE{
0 -> typeCnt \ 1st value
BEGIN typeCnt constant 1 ++> typeCnt
& } endlist?
UNTIL
do_ET ;
type{ InMainDic InOtherMod InThisMod } \ Relocatable addr types
\ SELECT{ defines a positional case construct - see Forth Dimensions vII p.51.
\ It is smaller and faster than the equivalent CASE construct, as long as
\ there are more than a couple of values. Values must be >= 0, and we give
\ a warning if a value > 50 is used, which could well be a boo-boo.
0 value MAXINDEX
\ Begin an indexed case structure
: SELECT{
postpone (sel)
maxindex \ Save on stack for nested selects
here \ Marks position of rtn addr offset word
0 w, \ Filled in later with RA offset
1 \ Dummy, so }SELECT knows when to stop
0 -> maxindex
postpone [ 240 ; immediate
: IS{ \ ( 240 index -- index here 240 )
?exec swap 240 ?pairs
dup 0< ?error 102
dup maxindex max -> maxindex
maxindex 500 > if msg# 85 then
here 240 postpone ] ; immediate
: }END
240 ?pairs
postpone (exit) postpone [ 240 ; immediate
: DEFAULT{
240 ?pairs
here 241 postpone ] ; immediate
: }SELECT \ ( ... index addr index addr (dflt-addr) 240/241 -- )
dup 240 =
IF drop here $ 4E75 w, \ No default - we make a dummy one
ELSE 241 ?pairs
THEN
-1 -> state postpone (exit)
\ Now build table:
maxindex 3+ 2* allot
( ... dflt-addr ) here - ( now relative to RA )
here 2- here maxindex 2* - 6 -
DO ( fill table with dflt addr initially )
dup i w!
2 +LOOP
drop maxindex here 2- w!
BEGIN ( index addr ) dup 1 =
NWHILE
( index addr ) here - here rot 2* - 6 - w!
REPEAT
drop ( tbl-offs-pos ) here over - swap w!
-> maxindex ; immediate
\ Testing:
\ +echo
\ : q db
\ select{ 3 is{ 23 }end
\ 2 is{ 22 }end
\ default{ 999
\ }select ;
\ key!
\ ========== Error diagnostics ===========
\ We use special values for nil handles and nil pointers. These are
\ odd addresses in ROM, so that if we do a word or long access we will
\ trap, and if we write a byte it at least won't go anywhere.
: .RTN \ ( addr -- )
cr ." From $" .h 4 spaces ;
: RANGE_ERR \ ( index range rtn-addr -- )
dup 1+ 0= ?error 128 \ Spurious range error
.rtn
dup -1 <
IF nip ?error 130 \ Not an indexed class
ELSE ." Range: " . ." Index: " .
true ?error 129
THEN ;
\ If we do software mult and div (on a 68000 which only allows a 16-bit divisor or
\ multiplicand) we also check for overflow and call ArithErr (vector) if ovfl occurs.
\ The appropriate err# is on the stack already, so here we just set ArithErr to Die.
\ This can be redirected as needed.
: X ['] range_err -> rngErr ['] die -> arithErr ;
x forget x
<" Args